package postprocessing;

import java.awt.Color;

import raytracing.PerspectiveCamera;
import structs.Vector2;
import structs.Vector3;
import utils.RenderPanel;

public class GodRayCalculator {

	private static final float Density = 1.2f;
	private static final int NUM_SAMPLES = 100;
	private static final float Weight = 0.02f;
	private static final float Decay = 0.988f;
	private static final float exposure = 1;

	public void processImage(ImageSampler sampler, Vector2 LightPosScreen, RenderPanel panel) {

		int maxCol = sampler.getWidth();
		int maxRow = sampler.getHeight();

		Vector3 tempResult = new Vector3(0, 0, 0);

		for (int col = 0; col < maxCol; col++) {
			for (int row = 0; row < maxRow; row++) {
				Vector2 pixelCoord = new Vector2(col, row);

				// Calculate vector from pixel to light source in screen space.
				Vector2 deltaTexCoord = new Vector2(pixelCoord.X - LightPosScreen.X, pixelCoord.Y - LightPosScreen.Y);
				// Divide by number of samples and scale by control factor.
				deltaTexCoord.multiply((float) 1.0f / NUM_SAMPLES * Density);
				// Store initial sample.
				Color color = sampler.getSample(pixelCoord);

				// Set up illumination decay factor.
				float illuminationDecay = 1.0f;

				// Evaluate summation from Equation 3 NUM_SAMPLES iterations.
				for (int i = 0; i < NUM_SAMPLES; i++) {

					// Step sample location along ray.
					pixelCoord.X -= deltaTexCoord.X;
					pixelCoord.Y -= deltaTexCoord.Y;

					// Retrieve sample at new location.
					Color sample = sampler.getSample(pixelCoord);

					// Apply sample attenuation scale/decay factors.
					tempResult = new Vector3(sample.getRed() * illuminationDecay * Weight, sample.getGreen()
							* illuminationDecay * Weight, sample.getBlue() * illuminationDecay * Weight);
					if (tempResult.X > 255)
						tempResult.X = 255;
					if (tempResult.Y > 255)
						tempResult.Y = 255;
					if (tempResult.Z > 255)
						tempResult.Z = 255;

					sample = new Color((int) tempResult.X, (int) tempResult.Y, (int) tempResult.Z);

					// Accumulate combined color.
					tempResult = new Vector3(color.getRed() + sample.getRed(), color.getGreen() + sample.getGreen(),
							color.getBlue() + sample.getBlue());

					if (tempResult.X > 255)
						tempResult.X = 255;
					if (tempResult.Y > 255)
						tempResult.Y = 255;
					if (tempResult.Z > 255)
						tempResult.Z = 255;

					color = new Color((int) tempResult.X, (int) tempResult.Y, (int) tempResult.Z);

					// Update exponential decay factor.
					illuminationDecay *= Decay;
				}
				// Output final color with a further scale control factor.
				tempResult = new Vector3(color.getRed() * exposure, color.getGreen() * exposure, color.getBlue()
						* exposure);

				if (tempResult.X > 255)
					tempResult.X = 255;
				if (tempResult.Y > 255)
					tempResult.Y = 255;
				if (tempResult.Z > 255)
					tempResult.Z = 255;

				color = new Color((int) tempResult.X, (int) tempResult.Y, (int) tempResult.Z);

				panel.drawPixel(maxRow - row, col, color);
			}
		}

		panel.saveImage("Data/autosave/autosavePostProcessing.png");
		System.out.println("Done postprocessing GodRays");

	}
}
